#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cta.impl.action.add_account.optimize2.add_optimize2_account_action import AddOptimize2AccountAction
from cta.impl.action.calculate_data.optimize2.calculate_optimize2_bias_data_action import \
    CalculateOptimize2BiasDataAction
from cta.impl.action.calculate_data.optimize2.calculate_optimize2_ma_data_action import CalculateOptimize2MaDataAction
from cta.impl.action.close_position.optimize2.optimize2_close_not_main_contract_action import \
    Optimize2CloseNotMainContractAction
from cta.impl.action.close_position.optimize2.optimize2_fluctuation_pattern_stop_loss_close_position_action import \
    Optimize2FluctuationPatternStopLossClosePositionAction
from cta.impl.action.close_position.optimize2.optimize2_multi_factor_close_position_action import \
    Optimize2MultiFactorClosePositionAction
from cta.impl.action.close_position.quant2.quant2_close_not_main_contract_action import Quant2CloseNotMainContractAction
from cta.impl.action.close_position.quant2.quant2_fluctuation_pattern_stop_loss_close_position_action import \
    Quant2FluctuationPatternStopLossClosePositionAction
from cta.impl.action.close_position.rule_close_position_action import RuleClosePositionAction
from cta.impl.action.filter.delete_not_main_contract_code_filter_action import DeleteNotMainContractCodeFilterAction
from cta.impl.action.filter.exclude_code_filter_action import ExcludeCodeFilterAction
from cta.impl.action.filter.normalization_variance120_filter_action import NormalizationVariance123FilterAction
from cta.impl.action.log.optimize2.optimize2_log_action import Optimize2LogAction
from cta.impl.action.log.quant2.common_log_action import CommonLogAction
from cta.impl.action.open_position.optimize2.optimize2_multi_factor_open_position_action import \
    Optimize2MultiFactorOpenPositionAction
from cta.impl.action.open_position.rule_open_position_action import RuleOpenPositionAction
from cta.impl.action.overweight.optimize2.optimize2_multi_factor_overweight_action import \
    Optimize2MultiFactorOverweightAction
from cta.impl.action.prepare_data.common_prepare_data_action import CommonPrepareDataAction
from cta.impl.action.underweight.optimize2.optimize2_multi_factor_underweight_action import \
    Optimize2MultiFactorUnderweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_close_position_action import \
    UpdateOptimize2AccountAfterClosePositionAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_open_position_action import \
    UpdateOptimize2AccountAfterOpenPositionAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_overweight_action import \
    UpdateOptimize2AccountAfterOverweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_after_underweight_action import \
    UpdateOptimize2AccountAfterUnderweightAction
from cta.impl.action.update_optimize2_account.update_optimize2_account_before_close_position_action import \
    UpdateOptimize2AccountBeforeClosePositionAction
from cta.impl.action.update_quant2_account.update_quant2_account_after_close_position_action import \
    UpdateQuant2AccountAfterClosePositionAction
from cta.impl.action.update_quant2_account.update_quant2_account_after_open_position_action import \
    UpdateQuant2AccountAfterOpenPosition
from cta.impl.action.update_quant2_account.update_quant2_account_before_close_position_action import \
    UpdateQuant2AccountBeforeClosePositionAction
from cta.impl.step.optimize2.add_optimize2_account_step import AddOptimize2AccountStep
from cta.impl.step.optimize2.calculate_optimize2_data_step import CalculateOptimize2DataStep
from cta.impl.step.optimize2.optimize2_close_position_step import Optimize2ClosePositionStep
from cta.impl.step.optimize2.optimize2_log_step import Optimize2LogStep
from cta.impl.step.optimize2.optimize2_open_position_step import Optimize2OpenPositionStep
from cta.impl.step.optimize2.optimize2_overweight_step import Optimize2OverweightStep
from cta.impl.step.optimize2.optimize2_underweight_step import Optimize2UnderweightStep
from cta.impl.step.optimize2.update_optimize2_account_after_close_position_step import \
    UpdateOptimize2AccountAfterClosePositionStep
from cta.impl.step.optimize2.update_optimize2_account_after_open_position_step import \
    UpdateOptimize2AccountAfterOpenPositionStep
from cta.impl.step.optimize2.update_optimize2_account_after_overweight_step import \
    UpdateOptimize2AccountAfterOverweightStep
from cta.impl.step.optimize2.update_optimize2_account_after_underweight_step import \
    UpdateOptimize2AccountAfterUnderweightStep
from cta.impl.step.optimize2.update_optimize2_account_before_close_position_step import \
    UpdateOptimize2AccountBeforeClosePositionStep
from cta.impl.step.quant2.quant2_close_position_step import Quant2ClosePositionStep
from cta.impl.step.quant2.common_log_step import CommonLogStep
from cta.impl.step.normalization_variance120_filter_step import NormalizationVariance120FilterStep
from cta.impl.step.quant2.quant2_open_position_step import Quant2OpenPositionStep
from cta.impl.step.prepare_data_step import PrepareDataStep
from cta.impl.step.responsibility_chain_begin_step import ResponsibilityChainBeginStep
from cta.impl.step.responsibility_chain_end_step import ResponsibilityChainEndStep
from cta.impl.step.quant2.update_quant2_account_after_close_position_step import UpdateQuant2AccountAfterClosePositionStep
from cta.impl.step.quant2.update_qunat2_account_before_close_position_step import UpdateQuant2AccountBeforeClosePositionStep
from cta.interface.strategy.abstract_strategy import AbstractStrategy
from web.manager.log_manager import LogManager

Logger = LogManager.get_logger(__name__)

class RuleStrategy(AbstractStrategy):
    """
    量化CTA--时序--规则：
    1.在120日方差上设置一个阈值A，如果大于这个阈值A就说明这个期货是趋势形态，否则就是震荡形态。
    2.由于有的期货收盘价很高，有的期货收盘价很低，因此要先对120日方差做归一化处理。
    3.如果是趋势形态，则当收盘价>=牛熊线时开多单，当收盘价<牛熊线时平多单，并且开空单，之后当收盘价>=牛熊线时平空单，再开多单，如此循环往复。
    4.如果是震荡形态，为最近120个交易日做线性拟合，如果斜率在正负10以内也认为是水平震荡，否则为震荡向上或震荡向下。当出现分型时就可以开仓或平仓，如此循环往复。此外还要有止损。
    """

    def __init__(self):
        super().__init__()

        ################################ 定义步骤（职责链设计模式） ################################
        self.responsibility_chain_begin_step = ResponsibilityChainBeginStep()
        # 量化
        self.update_quant2_account_before_close_position_step = UpdateQuant2AccountBeforeClosePositionStep(UpdateQuant2AccountBeforeClosePositionAction())
        self.prepare_data_step = PrepareDataStep(CommonPrepareDataAction())
        self.normalization_variance120_filter_step = NormalizationVariance120FilterStep(ExcludeCodeFilterAction(), DeleteNotMainContractCodeFilterAction(), NormalizationVariance123FilterAction())
        self.add_optimize2_account_step = AddOptimize2AccountStep(AddOptimize2AccountAction())
        self.quant2_close_position_step = Quant2ClosePositionStep(Quant2CloseNotMainContractAction(), Quant2FluctuationPatternStopLossClosePositionAction(), RuleClosePositionAction())
        self.update_quant2_account_after_close_position_step = UpdateQuant2AccountAfterClosePositionStep(UpdateQuant2AccountAfterClosePositionAction())
        self.quant2_open_position_step = Quant2OpenPositionStep(RuleOpenPositionAction())
        self.update_quant2_account_after_open_position_step = UpdateQuant2AccountAfterOpenPosition(UpdateQuant2AccountAfterOpenPosition())
        self.common_log_step = CommonLogStep(CommonLogAction())
        # 优化
        self.update_optimize2_account_before_close_position_step = UpdateOptimize2AccountBeforeClosePositionStep(UpdateOptimize2AccountBeforeClosePositionAction())
        self.optimize2_close_position_step = Optimize2ClosePositionStep(Optimize2CloseNotMainContractAction(), Optimize2FluctuationPatternStopLossClosePositionAction(), Optimize2MultiFactorClosePositionAction())
        self.update_optimize2_account_after_close_position_step = UpdateOptimize2AccountAfterClosePositionStep(UpdateOptimize2AccountAfterClosePositionAction())
        self.optimize2_open_position_step = Optimize2OpenPositionStep(Optimize2MultiFactorOpenPositionAction())
        self.update_optimize2_account_after_open_position_step = UpdateOptimize2AccountAfterOpenPositionStep(UpdateOptimize2AccountAfterOpenPositionAction())
        self.optimize2_multi_factor_underweight_step = Optimize2UnderweightStep(Optimize2MultiFactorUnderweightAction())
        self.update_optimize2_account_after_underweight_step = UpdateOptimize2AccountAfterUnderweightStep(UpdateOptimize2AccountAfterUnderweightAction())
        self.optimize2_multi_factor_overweight_step = Optimize2OverweightStep(Optimize2MultiFactorOverweightAction())
        self.update_optimize2_account_after_overweight_step = UpdateOptimize2AccountAfterOverweightStep(UpdateOptimize2AccountAfterOverweightAction())
        self.optimize2_log_step = Optimize2LogStep(Optimize2LogAction())
        self.calculate_optimize2_data_step = CalculateOptimize2DataStep(CalculateOptimize2MaDataAction(), CalculateOptimize2BiasDataAction())
        self.responsibility_chain_end_step = ResponsibilityChainEndStep()

        ################################ 定义步骤顺序（职责链设计模式） ################################
        self.responsibility_chain_begin_step.set_successor(self.update_quant2_account_before_close_position_step)
        # 量化
        self.update_quant2_account_before_close_position_step.set_successor(self.prepare_data_step)
        self.prepare_data_step.set_successor(self.normalization_variance120_filter_step)
        self.normalization_variance120_filter_step.set_successor(self.add_optimize2_account_step)
        self.add_optimize2_account_step.set_successor(self.quant2_close_position_step)
        self.quant2_close_position_step.set_successor(self.update_quant2_account_after_close_position_step)
        self.update_quant2_account_after_close_position_step.set_successor(self.quant2_open_position_step)
        self.quant2_open_position_step.set_successor(self.update_quant2_account_after_open_position_step)
        self.update_quant2_account_after_open_position_step.set_successor(self.common_log_step)
        self.common_log_step.set_successor(self.update_optimize2_account_before_close_position_step)
        # 优化
        self.update_optimize2_account_before_close_position_step.set_successor(self.optimize2_close_position_step)
        self.optimize2_close_position_step.set_successor(self.update_optimize2_account_after_close_position_step)
        self.update_optimize2_account_after_close_position_step.set_successor(self.optimize2_open_position_step)
        self.optimize2_open_position_step.set_successor(self.update_optimize2_account_after_open_position_step)
        self.update_optimize2_account_after_open_position_step.set_successor(self.optimize2_multi_factor_underweight_step)
        self.optimize2_multi_factor_underweight_step.set_successor(self.update_optimize2_account_after_underweight_step)
        self.update_optimize2_account_after_underweight_step.set_successor(self.optimize2_multi_factor_overweight_step)
        self.optimize2_multi_factor_overweight_step.set_successor(self.update_optimize2_account_after_overweight_step)
        self.update_optimize2_account_after_overweight_step.set_successor(self.optimize2_log_step)
        self.optimize2_log_step.set_successor(self.calculate_optimize2_data_step)
        self.calculate_optimize2_data_step.set_successor(self.responsibility_chain_end_step)

    def start(self):
        Logger.info('开始执行：量化CTA--时序--规则')

        super().exec()